package com.itheima.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.crypto.digest.BCrypt;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.itheima.entity.PageResult;
import com.itheima.entity.QueryPageBean;
import com.itheima.mapper.PermissionMapper;
import com.itheima.mapper.RoleMapper;
import com.itheima.mapper.UserMapper;
import com.itheima.pojo.*;
import com.itheima.service.UserService;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

@Service
@Transactional
public class UserServiceImpl implements UserService {
    //注入持久层
    @Autowired
    private UserMapper userMapper;
    @Autowired
    RoleMapper roleMapper;
    @Autowired
    PermissionMapper permissionMapper;

    @Override
    public User findUserByUsername(String username) {
        //查询对应的user对象
        User user = userMapper.findUserByUsername(username);

        //使用userId查询对应的角色集合
        Set<Role> roleset = userMapper.findRolesByUserId(user.getId());

        //遍历角色集合
        for (Role role : roleset) {
            //使用角色ID查询对应的权限集合
            Set<Permission> permissionSet = userMapper.findPermissionByRoleId(role.getId());

            //将权限集合赋值给到当前角色
            role.setPermissions(permissionSet);
        }

        //将角色集合赋值给当前的User对象
        user.setRoles(roleset);

        return user;
    }



//                            _ooOoo_
//                           o8888888o
//                           88" . "88
//                           (| -_- |)
//                            O\ = /O
//                        ____/`---'\____
//                      .   ' \\| |// `.
//                       / \\||| : |||// \
//                     / _||||| -:- |||||- \
//                       | | \\\ - /// | |
//                     | \_| ''\---/'' | |
//                      \ .-\__ `-` ___/-. /
//                   ___`. .' /--.--\ `. . __
//                ."" '< `.___\_<|>_/___.' >'"".
//               | | : `- \`.;`\ _ /`;.`/ - ` : | |
//                 \ \ `-. \_ __\ /__ _/ .-` / /
//         ======`-.____`-.___\_____/___.-`____.-'======
//                            `=---='
//
//         .............................................
//                  佛祖镇楼                  BUG辟易
//          佛曰:
//                  写字楼里写字间，写字间里程序员；
//                  程序人员写程序，又拿程序换酒钱。
//                  酒醒只在网上坐，酒醉还来网下眠；
//                  酒醉酒醒日复日，网上网下年复年。
//                  但愿老死电脑间，不愿鞠躬老板前；
//                  奔驰宝马贵者趣，公交自行程序员。
//                  别人笑我忒疯癫，我笑自己命太贱；
//                  不见满街漂亮妹，哪个归得程序员？

    @Override
    public User findByUsername(String username) {
        //根据用户名查询用户
        User user = userMapper.findByUserName(username);
        if (null != user) {
            //根据用户id查询用户角色
            Set<Role> roles = roleMapper.findByUserId(user.getId());
            if (CollectionUtil.isNotEmpty(roles)) {
                //查询此角色的所有ids
                List<Integer> ids = getRoleIds(roles);
                //根据ids查询此用户的所有权限
                Set<Permission> permissions = permissionMapper.findByRoleIds(ids);
                user.setPermissions(permissions);
            }
        }
        return user;
    }

    private List<Integer> getRoleIds(Set<Role> roles) {
        List<Integer> ids = new ArrayList<>();
        for (Role role : roles) {
            ids.add(role.getId());
        }
        return ids;
    }

    /**
     * 新增
     * @author Qifei
     * @param user
     * @param roleIds
     */
    @Override
    public void add(User user, Integer[] roleIds) {
        user.setPassword(BCrypt.hashpw("1234"));
        userMapper.add(user);
        if (null != roleIds && roleIds.length != 0) {
            userMapper.setUserAndRoles(user.getId(), roleIds);
        }
    }

    /**
     * 分页查询
     * @author Qifei
     * @param queryPageBean
     * @return
     */
    @Override
    public PageResult findPage(QueryPageBean queryPageBean) {
        Page page = PageHelper.startPage(queryPageBean.getCurrentPage(), queryPageBean.getPageSize());
        List<User> list = userMapper.findPage(queryPageBean.getQueryString());
        return new PageResult(page.getTotal(), list);
    }

    /**
     * 删除
     * @author Qifei
     * @param id
     * @param username
     */
    @Override
    public void delete(Integer id, String username) {
        String username1 = userMapper.findUsernameByUserId(id);
        if (username.equals(username1)) {
            throw new RuntimeException("想删除自己，你怕不是个憨憨");
        }
        userMapper.deleteUserAndRoles(id);
        userMapper.delete(id);
    }

    /**
     * 编辑
     * @author Qifei
     * @param user
     * @param roleIds
     */
    @Override
    public void edit(User user, Integer[] roleIds) {
        userMapper.deleteUserAndRoles(user.getId());
        userMapper.edit(user);
        if (null != roleIds && roleIds.length != 0) {
            userMapper.setUserAndRoles(user.getId(), roleIds);
        }
    }

    @Override
    public List<Integer> findRoleIdsByUserId(Integer userId) {
        return userMapper.findRoleIdsByUserId(userId);
    }

    @Override
    public User findByUserId(Integer userId) {
        return userMapper.findByUserId(userId);
    }

    //实现动态菜单的实现类
    @Override
    public List<MenuTitle> findAllMenuByRole(String name) {
        //通过名字三表联查得到所有的菜单对象
        User user = userMapper.findUserByUsername(name);
        //得到所有的菜单Id
        List<Integer> listMenu = userMapper.findAllByUserIdToMenuId(user.getId());

        //创建两个容器 level=1和level=2 爸爸和儿子
        List<MenuTitle> listMenuFa = new ArrayList<>();
        List<MenuTitle> listMenuCh = new ArrayList<>();

        //循环所有的菜单id（父亲儿子在一张表中）
        for (Integer menuId : listMenu) {
            //得到level=1的所有菜单对象
            MenuTitle menuFa = userMapper.findAllFaByMenuId(menuId);
            //得到level=2的所有菜单对象
            MenuTitle menuCh = userMapper.findAllChByMenuId(menuId);

            //当不为空时把得到的所有儿子对象装进儿子容器
            if (menuFa != null) {
                listMenuFa.add(menuFa);
            }

            //当不为空时把得到的所有父亲对象装进父亲容器
            if (menuCh != null) {
                listMenuCh.add(menuCh);
            }
        }

        //循环父亲容器
        for (MenuTitle menuFa : listMenuFa) {
            //创建容器放每个父亲对应的儿子们
            List<MenuTitle> listMenuToCh = new ArrayList<>();
            //循环儿子容器
            for (MenuTitle menuCh : listMenuCh) {
                //在所有的儿子里找对应的父亲
                if (menuCh.getParentMenuId().equals(menuFa.getId())) {
                    //找到一个就把一个儿子装进父亲对应儿子的容器
                    listMenuToCh.add(menuCh);
                }
            }
            //把父亲对应儿子的容器装进了该  父对象的口袋里  实体类里的某一属性
            menuFa.setChildren(listMenuToCh);
        }
        //返回父亲容器
        return listMenuFa;
    }

}
